#!/usr/local/bin/bash
# Sample script for lock any IP address or any subnet.
# Use iptables and bash arrays.
# Tested in Debian and Slackware Linux.
#
# help & discussion: http://forum.drbatty.ru/viewtopic.php?f=77&t=8981 (russian)

IPTABLES=$(find /usr/sbin/ /sbin/ -name "iptables" | head -n1)
echo "Found $IPTABLES."

BLACKLIST_FILE="/usr/local/etc/black_list_ip.txt"
if [ ! -r "$BLACKLIST_FILE" ]; then
	echo "Create file '$BLACKLIST_FILE'."
	exit 1
fi

declare -A BLACKLIST
declare -a BLACKLIST_NUM

TMP=$(mktemp)

echo "Dropped IP list."
COUNT=0
$IPTABLES -L INPUT -n --line-numbers |\
	sed -rn '
		/^Chain INPUT/,/^Chain FORWARD/{
			/^Chain|^$|^num /d;
			s/^([0-9]+)\s+(\S+)\s+(\S+\s+){2}(([0-9]+\.){3}[0-9]+(\/[0-9]{1,2})?)\s+.*/\1 \2 \4/p
		}' >$TMP
while read num target ip
do
	echo "$num. $ip $target"
	BLACKLIST[$ip]=$target
	BLACKLIST_NUM[$num]=$ip
	if [ $target == "DROP" ]; then
		(( COUNT++ ))
	fi
done <$TMP
echo "--------------"
echo "Blocked $COUNT ip."
echo

echo "Locked..."
sed -rn '
	/^\s*#|^\s*$/d
	s/^(([0-9]+\.){3}[0-9]+(\/[0-9]{1,2})?)(\s+.*)?$/\1/p
	' "$BLACKLIST_FILE" >$TMP
while read ip
do
	echo "ip: $ip BLACKLIST: '${BLACKLIST["$ip"]}' '${!BLACKLIST[@]}' '${BLACKLIST[@]}'"
	echo "BLACKLIST"
	for k in ${!BLACKLIST[@]}
	do
		echo "[$k] => '${BLACKLIST[$k]}'"
	done
	if [ $ip == "0.0.0.0/0" ]; then
		echo "$ip skip..."
	elif [ "${BLACKLIST[$ip]}" == "DROP" ]; then
		echo "$ip already locked."
	else
		echo "Locked $ip..."
		echo "${BLACKLIST[$ip]}"
		$IPTABLES -A INPUT -t filter -s $ip -j DROP
		err=$?
		if [ "$err" == 0 ]; then
			echo "OK."
		else
			echo "Exit in error code $err."
			rm --force $TMP
			exit $err
		fi
	fi
	BLACKLIST[$ip]="DROPPED"
	echo "--"
done <$TMP
echo "--------------"
echo "OK."
echo

echo "Unlocked..."
DELTA=0
for COUNT in ${!BLACKLIST_NUM[@]}
do
	ip=${BLACKLIST_NUM[$COUNT]}
	if [ $ip == "0.0.0.0/0" ]; then
		echo "$ip skip..."
	elif [ "${BLACKLIST[$ip]}" == "DROP" ]; then
		(( num = COUNT - DELTA ))
		echo "Unlock $COUNT. $ip ($num)..."
		$IPTABLES -D INPUT $num
		err=$?
		if [ "$err" == 0 ]; then
			echo "OK."
		else
			echo "Exit in error code $err."
			rm --force $TMP
			exit $err
		fi
		(( DELTA++ ))
	fi
done
echo "--------------"
echo "OK."



rm --force $TMP

